package com.xcity.game.financial;

import java.util.ArrayList;
import java.util.List;

import com.xcity.db.entity.Financial;
import com.xcity.db.entity.Player;
import com.xcity.db.mapper.FinancialMapper;
import com.xcity.game.ISystem;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.skill.SkillTypes;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.request.BuyFinancialRequest;
import com.xcity.pomelo.request.GetFinancialListRequest;
import com.xcity.pomelo.request.GetMyFinancialsRequest;
import com.xcity.pomelo.request.ReceiveFinancialInterestRequest;
import com.xcity.pomelo.response.BuyFinancialResponse;
import com.xcity.pomelo.response.FinancialListResponse;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.MyFinancialsResponse;
import com.xcity.pomelo.response.ReceiveFinancialInterestResponse;
import com.xcity.util.DBUtils;

import naga.x.App;
import naga.x.game.template.TemplateService;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.Service;
import naga.x.service.ServiceException;

@OPHandler
public class FinancialService implements Service, ISystem {

	private List<Financial> products;
	public static FinancialTemplate defaultTemplate;
	
	@Override
	public void startup() throws ServiceException {
		List<Financial> list = DBUtils.selectList(FinancialMapper.STATEMENT_FIND_BY_PHASE, 1);
		
		List<FinancialTemplate> templates = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(FinancialTemplate.class);
		int size = templates.size();
		products = new ArrayList<Financial>(size);
		for (int i = 0; i < size; i++) {
			FinancialTemplate template = templates.get(i);
			if (defaultTemplate == null) {
				defaultTemplate = template;
			}
			Financial f = find(list, template.getId());
			if (f == null) {
				f = new Financial(template);
				DBUtils.save(f, FinancialMapper.class);
			}
			products.add(f);
		}
	}
	
	private Financial find(List<Financial> products, int financialId) {
		if (products == null || products.isEmpty()) {
			return null;
		}
		for (int i = 0, size = products.size(); i < size; i++) {
			Financial f = products.get(i);
			if (f.getFinancialId() == financialId) {
				return f;
			}
		}
		return null;
	}
	
	public Financial find(int financialId) {
		return find(products, financialId);
	}

	@Override
	public void shutdown() throws ServiceException {
		for (int i = products.size() - 1; i >= 0; i--) {
			Financial f = products.get(i);
			DBUtils.update(f, FinancialMapper.class);
		}
	}

	@Override
	public String getId() {
		return getClass().getName();
	}
	
	@PomeloOP(PomeloRoute.BUY_FINANCIAL)
	protected void requestBuy(Session session, BuyFinancialRequest req) {
		Financial product = find(req.getFinancialId());
		if (product == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_NOT_EXIST));
			return;
		}
		if (product.isOver()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_SOLD_OUT));
			return;
		}
		if (req.getNum() <= 0) {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_BUY_AT_LEAST_ONE));
			return;
		}
		FinancialTemplate template = product.getTemplate();
		if (req.getNum() > template.getLimit()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_CANT_EXCEED_MAX_NUM));
			return;
		}
//		if (req.getMoney() < product.getTemplate().getMin()) {
//			session.send(new ErrorResponse("不能低于起投金额"));
//			return;
//		}
		Player player = session.getClient();
		if (player.getFinancials().count(req.getFinancialId()) >= template.getLimit()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_MAXED));
			return;
		}
		int num = req.getNum(); // 购买份数
		long price = template.getMin(); // 每份价格
		long cost = num * price;
		if (!player.costGold(cost, Cause.BUY_FINANCIAL)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.GOLD_NOT_ENOUGH));
			return;
		}
		product.addMoney(cost);
		// 宠物技能加成
		Integer ratio = player.getPets().calc(SkillTypes.SKILL_INCREASE_FINANCIAL_INTEREST);
		if (ratio != null) {
			ratio = 100 + ratio;
		} else {
			ratio = 100;
		}
		// 计算单个产品总利息
		long interest = template.getRate() * price * template.getPeriod() / 36500 * ratio / 100;
		while (num-- > 0) {
			player.getFinancials().add(new PlayerFinancial(product.getFinancialId(), price, interest, template.getPeriod()));
		}
		session.send(new BuyFinancialResponse(req.getSerial(), product, player));
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_USE_SYSTEM, player, getSystemId(), req.getNum());
	}
	
	@PomeloOP(PomeloRoute.FINANCIAL_LIST)
	protected void requestList(Session session, GetFinancialListRequest req) {
		session.send(new FinancialListResponse(req.getSerial(), session.getClient(), products));
	}
	
	@PomeloOP(PomeloRoute.GET_MY_FINANCIALS)
	protected void requestMyFinancials(Session session, GetMyFinancialsRequest req) {
		Player player = session.getClient();
		session.send(new MyFinancialsResponse(req.getSerial(), player));
	}
	
	@PomeloOP(PomeloRoute.RECEIVE_FINANCIAL_INTEREST)
	protected void requestReceiveInterest(Session session, ReceiveFinancialInterestRequest req) {
		Player player = session.getClient();
		boolean succ = player.getFinancials().receiveInterest(req.getId());
		if (succ) {
			session.send(new ReceiveFinancialInterestResponse(req.getSerial(), req.getId(), player));
		} else {
			session.send(new HintResponse(req.getSerial(), MessageConst.FINANCIAL_HAVE_NO_INTEREST));
		}
	}

	@Override
	public int getSystemId() {
		return SYS_FINANCIAL;
	}
	
}
